package hos.file.utils;

import android.content.Context;
import android.net.Uri;
import android.text.TextUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import hos.file.media.FileType;
import hos.file.media.MediaUri;
import hos.file.provider.FileProviderX;
import top.zibin.luban.CompressionPredicate;
import top.zibin.luban.Luban;

/**
 * <p>Title: ImageZipUtils </p>
 * <p>Description: 图片压缩工具 </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2024-03-15 22:40
 */
public class ZipImageUtils {

    /**
     * 压缩率 ，默认100
     */
    protected static int leastCompressSize = 100;
    /**
     * 图片的最小压缩大小 默认 1M
     */
    protected static long minCompressSize = 1048576;

    public static int getLeastCompressSize() {
        return leastCompressSize;
    }

    public static long getMinCompressSize() {
        return minCompressSize;
    }



    public static File uri2FileZipImage(Context context, Uri uri,
                                        long minCompressSize, int leastCompressSize,
                                        ZipImageUtils.OnImageZipListener listener) {
        File file = FileProviderX.uri2File(context, uri);
        if (file == null) {
            return null;
        }
        if (FileType.isIMAGE(file.getAbsolutePath())) {
            return ZipImageUtils.zipImageFile(context, uri,
                    minCompressSize, leastCompressSize, listener);
        }
        return file;
    }

    public static File fileZipImage(Context context, File file) {
        return fileZipImage(context, file,
                ZipImageUtils.getMinCompressSize(), ZipImageUtils.getLeastCompressSize(), null);
    }

    public static File fileZipImage(Context context, File file,
                                    long minCompressSize) {
        return fileZipImage(context, file,
                minCompressSize, ZipImageUtils.getLeastCompressSize(), null);
    }

    public static File fileZipImage(Context context, File file,
                                    long minCompressSize,
                                    ZipImageUtils.OnImageZipListener listener) {
        return fileZipImage(context, file,
                minCompressSize, ZipImageUtils.getLeastCompressSize(), listener);
    }

    public static File fileZipImage(Context context, File file,
                                    long minCompressSize, int leastCompressSize,
                                    ZipImageUtils.OnImageZipListener listener) {
        if (file == null) {
            return null;
        }
        if (FileType.isIMAGE(file.getAbsolutePath())) {
            return ZipImageUtils.zipImageFile(context, file,
                    minCompressSize, leastCompressSize, listener);
        }
        return file;
    }

    public static List<File> uri2FileListZipImage(Context context, List<Uri> uriList,
                                                  long minCompressSize, int leastCompressSize,
                                                  ZipImageUtils.OnImageZipListener listener) {
        List<File> pathList = new ArrayList<>();
        for (Uri uri : uriList) {
            File file = FileProviderX.uri2File(context, uri);
            if (file == null) {
                continue;
            }
            if (FileType.isIMAGE(file.getAbsolutePath())) {
                // 如果是图片的话，就需要进行压缩判断
                File zipImageFile = ZipImageUtils.zipImageFile(context, file,
                        minCompressSize, leastCompressSize, listener);
                if (zipImageFile != null) {
                    // 压缩成功
                    pathList.add(zipImageFile);
                    continue;
                }
                // 压缩失败，跳过压缩
            }
            pathList.add(file);
        }
        return pathList;
    }

    public static List<File> fileListZipImage(Context context, List<File> fileList,
                                              long minCompressSize, int leastCompressSize,
                                              ZipImageUtils.OnImageZipListener listener) {
        List<File> pathList = new ArrayList<>();
        for (File file : fileList) {
            if (file == null) {
                continue;
            }
            if (FileType.isIMAGE(file.getAbsolutePath())) {
                // 如果是图片的话，就需要进行压缩判断
                File zipImageFile = ZipImageUtils.zipImageFile(context, file,
                        minCompressSize, leastCompressSize, listener);
                if (zipImageFile != null) {
                    // 压缩成功
                    pathList.add(zipImageFile);
                    continue;
                }
                // 压缩失败，跳过压缩
            }
            pathList.add(file);
        }
        return pathList;
    }


    /**
     * 对图片进行压缩
     *
     * @param uri 需要压缩的Uri
     */

    public static File zipImageFile(Context context, Uri uri) {
        return zipImageFile(context, uri, minCompressSize, leastCompressSize, null);
    }

    /**
     * 对图片进行压缩
     *
     * @param uri 需要压缩的Uri
     */

    public static File zipImageFile(Context context, Uri uri,
                                    long minCompressSize) {
        return zipImageFile(context, uri, minCompressSize, leastCompressSize, null);
    }

    /**
     * 对图片进行压缩
     *
     * @param uri 需要压缩的Uri
     */

    public static File zipImageFile(Context context, Uri uri,
                                    long minCompressSize, int leastCompressSize) {
        return zipImageFile(context, uri, minCompressSize, leastCompressSize, null);
    }

    /**
     * 对图片进行压缩
     *
     * @param uri 需要压缩的Uri
     */

    public static File zipImageFile(Context context, Uri uri,
                                    OnImageZipListener listener) {
        return zipImageFile(context, uri, minCompressSize, leastCompressSize, listener);
    }

    /**
     * 对图片进行压缩
     *
     * @param uri 需要压缩的Uri
     */

    public static File zipImageFile(Context context, Uri uri,
                                    long minCompressSize,
                                    OnImageZipListener listener) {
        return zipImageFile(context, uri, minCompressSize, leastCompressSize, listener);
    }

    /**
     * 对图片进行压缩
     *
     * @param uri 需要压缩的Uri
     */

    public static File zipImageFile(Context context, Uri uri,
                                    long minCompressSize, int leastCompressSize,
                                    OnImageZipListener listener) {
        File file = FileProviderX.uri2File(context, uri);
        if (file == null) {
            // 附件获取失败
            return null;
        }
        return zipImageFile(context, file, minCompressSize, leastCompressSize, listener);
    }

    /**
     * 对图片进行压缩
     *
     * @param file 需要压缩的file
     */

    public static File zipImageFile(Context context, File file) {
        return zipImageFile(context, file, minCompressSize, leastCompressSize, null);
    }

    /**
     * 对图片进行压缩
     *
     * @param file 需要压缩的file
     */

    public static File zipImageFile(Context context, File file,
                                    long minCompressSize) {
        return zipImageFile(context, file, minCompressSize, leastCompressSize, null);
    }

    /**
     * 对图片进行压缩
     *
     * @param file 需要压缩的file
     */

    public static File zipImageFile(Context context, File file,
                                    long minCompressSize, int leastCompressSize) {
        return zipImageFile(context, file, minCompressSize, leastCompressSize, null);
    }

    /**
     * 对图片进行压缩
     *
     * @param file 需要压缩的file
     */

    public static File zipImageFile(Context context, File file,
                                    OnImageZipListener listener) {
        return zipImageFile(context, file, minCompressSize, leastCompressSize, listener);
    }

    /**
     * 对图片进行压缩
     *
     * @param file 需要压缩的file
     */

    public static File zipImageFile(Context context, File file,
                                    long minCompressSize,
                                    OnImageZipListener listener) {
        return zipImageFile(context, file, minCompressSize, leastCompressSize, listener);
    }

    /**
     * 对图片进行压缩
     *
     * @param file 需要压缩的file
     */

    public static File zipImageFile(Context context, File file,
                                    long minCompressSize, int leastCompressSize,
                                    OnImageZipListener listener) {
        if (!FileUtils.isFileExists(context, file)) {
            // 附件不存在
            return null;
        }
        if (minCompressSize == 0) {
            // 不需要进行压缩
            return file;
        }
        // 需要压缩
        long fileSourceSize = FileUtils.fileSize(file);
        if (fileSourceSize <= minCompressSize) {
            // 大小没有到达，不需要压缩
            return file;
        }
        try {
            // 对文件进行压缩
            List<File> fileList;
            if (listener != null) {
                fileList = listener.onZip(context, file, leastCompressSize);
            } else {
                fileList = Luban.with(context)  //context
                        .load(file)  // 需要压缩的图片file
                        .ignoreBy(leastCompressSize)   //压缩率 ，默认100
                        .setTargetDir(file.getParent())  //压缩后文件目录
                        .filter(new CompressionPredicate() {
                            @Override
                            public boolean apply(String path) {
                                return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
                            }
                        }).get();
            }
            // 这里一次只压缩一次文件
            File compressFile = fileList.get(0);
            if (!FileUtils.isFileExists(context, compressFile)) {
                // 压缩文件不存在
                return file;
            }
            // 覆盖之前的图片
            if (FileIOUtils.writeFileFromFile(file, compressFile)) {
                // 覆盖成功,删除压缩后的图片
                if (!FileUtils.delete(compressFile)) {
                    // 删除压缩文件失败
                    return file;
                }
                return file;
            }
            // 覆盖失败，需要删除之前的图片，在对压缩后的图片进行重命名
            String fileAbsolutePath = file.getAbsolutePath();
            String fileStart = fileAbsolutePath.split("\\.")[0];
            String fileEnd = compressFile.getAbsolutePath().split("\\.")[1];
            String filePathNew = fileStart + "." + fileEnd;
            if (!FileUtils.delete(file)) {
                // 删除源文件失败
                return compressFile;
            }
            if (!FileUtils.rename(compressFile, filePathNew)) {
                // 重命名失败
                return compressFile;
            }
            MediaUri.updateSystemPhotoAlbum(context, compressFile.getAbsolutePath());
            return compressFile;
        } catch (IOException e) {
            e.printStackTrace();
            // 压缩失败
            return file;
        }
    }

    public static interface OnImageZipListener {
        List<File> onZip(Context context, File file, int leastCompressSize);
    }
}
